package renamer;

import static eabox.FileUtil.CUE_PATTERN;
import static eabox.FileUtil.MUSIC_FILE_PATTERN;
import static eabox.FileUtil.getFileExt;
import static eabox.FileUtil.getFilesList;
import static eabox.FileUtil.getParentName;
import static eabox.FileUtil.isUTF8;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class CueProcessor implements FileProcessor {
	// Correct the title property base on the cue's file name
	private String correctTitle(File cue) {
		String fileName = cue.getName();
		int startIndex = fileName.indexOf("-") + 2;
		int endIndex = fileName.lastIndexOf(".");
		return fileName.substring(startIndex, endIndex);
	}

	// Correct the Performer property base on the cue's file name
	private String correctPerformer(File cue) {
		String fileName = cue.getName();
		int startIndex = 0;
		int endIndex = fileName.indexOf("-") - 1;
		return fileName.substring(startIndex, endIndex);
	}

	// Correct the path property to corresponding music file extension
	private String correctCueExt(File cue) {
		File parent = cue.getParentFile();
		File musicFile = getFilesList(parent, MUSIC_FILE_PATTERN).get(0);
		return getFileExt(musicFile);
	}

	private String formatReadLine(File file, String line) {
		String PERFORMER_PROPERTY = "PERFORMER \"%s\"%n";
		String TITLE_PROPERTY = "TITLE \"%s\"%n";
		String FILE_PROPERTY = "FILE \"%s.%s\" WAVE%n";
		String name = getParentName(file);
		String ext = correctCueExt(file);
		String performer = correctPerformer(file);
		String title = correctTitle(file);
		if (line.matches("FILE.*WAVE"))
			return String.format(FILE_PROPERTY, name, ext);
		else if (line.matches("PERFORMER.*"))
			return String.format(PERFORMER_PROPERTY, performer);
		else if (line.matches("TITLE.*"))
			return String.format(TITLE_PROPERTY, title);
		else
			return line + "\n";
	}

	private String formatCueContent(File file, String encoding) {
		StringBuilder sb = new StringBuilder();
		String s;
		// Read and format cue file content into a StringBuilder
		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(
					new FileInputStream(file), encoding));
			while ((s = in.readLine()) != null)
				sb.append(formatReadLine(file, s));
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	private void backupCue(File file) {
		File backupFile = new File(file.getPath() + ".bak");
		file.renameTo(backupFile);
	}

	private void processCue(File file) {
		String encoding = isUTF8(file) ? "UTF8" : "GBK";
		try {
			// Format cue file content
			String formattedCueContent = formatCueContent(file, encoding);
			// Backup the original cue file
			backupCue(file);
			// Write a new cue file with the StringBuilder content
			BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(file), encoding));
			out.write(formattedCueContent);
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void process(File dir) {
		try {
			if (!dir.exists())
				throw new FileNotFoundException(dir.getAbsolutePath()
						+ "not found!");
			if (dir.isDirectory())
				for (File file : getFilesList(dir, CUE_PATTERN))
					processCue(file);
			else
				processCue(dir);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
